package com.fxl.majiang.message.output;

import com.fxl.majiang.enums.TilesEnum;
import com.fxl.majiang.enums.TilesGroupTypeEnum;
import com.fxl.majiang.room.Player;
import com.fxl.majiang.room.TilesGroup;
import lombok.Data;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author fengxinglei
 * @date 2022/8/18 23:38
 * @description TODO
 */
@Data
public class OutputReconnectMsgData implements OutputMessageData {
    private static final long serialVersionUID = 9197114710866889228L;

    private String name;

    private int seat;

    // 剩余的牌数量
    private int leftTilesCount;
    // 正在出牌的userId
    private String playingUserId;

    // 座子上的最近一张打出的牌
    private TilesEnum lastTile;

    // 能够拥有的操作
    private CanOperation canOperation = new CanOperation();

    // 可以上家这张牌的牌组
    private List<List<TilesEnum>> chiItGroups;

    // 可以暗杠的牌组
    private List<TilesEnum> anGangTiles;

    // 摸牌后可以选择明杠的牌
    private List<TilesEnum> mingGangTilesAfterGrabbing;

    // 花暗杠的牌组
    private List<List<TilesEnum>> huaAnGangGroups;

    // 当前拥有的牌
    private List<TilesEnum> ownedTiles = new ArrayList<>();

    // 百搭牌
    private List<TilesEnum> versatileTiles = new ArrayList<>();

    // 吃、碰、杠等牌组
    private List<TilesGroup> ownedTilesGroup = new ArrayList<>();

    // 花牌牌组
    private List<TilesGroup> ownedHuaTilesGroup = new ArrayList<>();

    // 打出的牌
    private List<TilesEnum> playedTiles = new ArrayList<>();

    // 上家
    private PlayingUser previousInfo;

    // 下家
    private PlayingUser nextInfo;

    // 对家
    private PlayingUser oppositeInfo;

    public void setSelfInfo(String name, Player player) {
        this.name=name;
        this.seat = player.getSeat().getCode();
        this.ownedTiles = player.getOwnedTiles();
        this.ownedTilesGroup = player.getOwnedTilesGroup();
        this.ownedHuaTilesGroup = player.getOwnedHuaTilesGroup();
        this.playedTiles = player.getPlayedTiles();
    }
    public void setPreviousInfo(String name, Player player) {
        if (player != null) {
            this.previousInfo = new PlayingUser(name, player);
        }
    }

    public void setNextInfo( String name, Player player) {
        if (player != null) {
            this.nextInfo = new PlayingUser(name, player);
        }
    }

    public void setOppositeInfo(String name, Player player) {
        if (player != null) {
            this.oppositeInfo = new PlayingUser(name, player);
        }
    }

    public void setCanBuHuaWhenStart(boolean canBuHuaWhenStart) {
        this.canOperation.setBuHuaWhenStart(canBuHuaWhenStart);
    }

    public void setCanBuHua(boolean canBuHua) {
        this.canOperation.setBuHua(canBuHua);
    }

    public void setCanChi(boolean canChi) {
        this.canOperation.setChi(canChi);
    }

    public void setCanPeng(boolean canPeng) {
        this.canOperation.setPeng(canPeng);
    }

    public void setCanGangIt(boolean canGangIt) {
        this.canOperation.setGangIt(canGangIt);
    }

    public void setCanMingGangAfterGrabbing(boolean canMingGangAfterGrabbing) {
        this.canOperation.setMingGangAfterGrabbing(canMingGangAfterGrabbing);
    }

    public void setCanHuaAnGang(boolean canHuaAnGang) {
        this.canOperation.setHuaAnGang(canHuaAnGang);
    }

    public void setCanAnGang(boolean canAnGang) {
        this.canOperation.setAnGang(canAnGang);
    }

    public void setCanDianPao(boolean canDianPao) {
        this.canOperation.setDianPao(canDianPao);
    }

    public void setCanZiMo(boolean canZiMo) {
        this.canOperation.setZiMo(canZiMo);
    }

    @Data
    public class PlayingUser {
        private String userId;

        private String name;

        /**
         * 座位
         * @see com.fxl.majiang.enums.SeatEnum
         */
        private int seat;

        // 用户当前拥有的牌数量
        private int ownedTilesCount;

        // 用户吃、碰、杠等牌组
        private List<TilesGroup> ownedTilesGroup = new ArrayList<>();

        // 用户花牌牌组
        private List<TilesGroup> ownedHuaTilesGroup = new ArrayList<>();

        // 用户打出的牌
        private List<TilesEnum> playedTiles = new ArrayList<>();

        public PlayingUser(String name, Player player) {
            this.userId = player.getUserId();
            this.name = name;
            this.seat = player.getSeat().getCode();
            this.ownedTilesCount = player.getOwnedTiles().size();
            this.playedTiles = player.getPlayedTiles();
            this.ownedHuaTilesGroup = player.getOwnedHuaTilesGroup();
            if (!CollectionUtils.isEmpty(player.getOwnedTilesGroup())) {
                player.getOwnedTilesGroup().stream().forEach(group -> {
                    // 如果是暗杠，则隐藏牌
                    if (group.getType() == TilesGroupTypeEnum.AN_GANG || group.getType() == TilesGroupTypeEnum.AN_GANG) {
                        this.ownedTilesGroup.add(new TilesGroup(group.getType(), new ArrayList<>()));
                    } else {
                        this.ownedTilesGroup.add(group);
                    }
                });
            }
        }
    }

    /**
     * 可以拥有的操作
     */
    @Data
    private class CanOperation {
        private boolean buHuaWhenStart;// 起手补花
        private boolean buHua; // 普通补花
        private boolean chi; // 吃
        private boolean peng; // 碰
        private boolean gangIt; // 杠张用户打出的牌
        private boolean mingGangAfterGrabbing;// 抓牌之后是否可以明杠
        private boolean huaAnGang; // 花暗杠
        private boolean anGang; // 暗杠
        private boolean dianPao; // 点炮胡
        private boolean ziMo;// 自摸胡
    }
}
